package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.tbit.common.entity.view.Result;
import com.tbit.uqbike.object.pojo.Account;
import com.tbit.uqbike.object.pojo.dto.RevenueDTO;
import com.tbit.uqbike.object.pojo.vo.AccountDayStatOtherDetailVO;
import com.tbit.uqbike.object.pojo.vo.RevenueGroupDayVO;
import com.tbit.uqbike.object.pojo.vo.RevenueVO;
import com.tbit.uqbike.service.business.RevenueService;
import com.tbit.uqbike.webmanager.dao.capital.BadOrderDao;
import com.tbit.uqbike.webmanager.dao.core.AccountDao;
import com.tbit.uqbike.webmanager.dao.stat.AccountDayStatDao;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 财务统计-营收统计
 * @author <a href="mailto:liu.haoxiang@tbit.com.cn">BUGXiang</a>
 * @version 1.0
 * @since 2025-2-10
 */
@Service
public class RevenueServiceImpl implements RevenueService {

    @Resource
    private AccountDayStatDao accountDayStatDao;
    @Resource
    private BadOrderDao badOrderDao;
    @Resource
    private AccountDao accountDao;


    /**
     * 获取营收统计
     * @param dto dto
     * @return
     */
    @Override
    public Result<Object> getRevenue(RevenueDTO dto) {

        List<Integer> accountIdList = new ArrayList<>();
        if (StrUtil.isNotEmpty(dto.getAccountIds())) {
            accountIdList.addAll(Arrays.stream(dto.getAccountIds().split(","))
                    .map(String::trim)  // 去除每个元素的前后空格
                    .map(Integer::parseInt)
                    .collect(Collectors.toList()));
        }
        //区域名称
        Map<Integer, String> accountMap = accountDao.getById(dto.getBrandId()).stream()
                .collect(Collectors.toMap(Account::getAccountId, Account::getName));

        //汇总
        if (0 == dto.getType()){

            //校验时间范围不能超过6个月
            if (DateUtil.betweenMonth(dto.getStartTime(), dto.getEndTime(), true) > 6) {
                return Result.error("时间范围不能超过6个月");
            }

            //获取预统计数据
            Map<Integer, RevenueVO> revenueMap = accountDayStatDao.getRevenue(parseTime(dto.getStartTime()),
                    parseTime(dto.getEndTime()), dto.getBrandId(), accountIdList);
            //获取其他收支数据
            List<AccountDayStatOtherDetailVO> vos = badOrderDao.selectOtherFinancial(dto.getStartTime(),
                    dto.getEndTime(), accountIdList, dto.getBrandId());
            Map<Integer, AccountDayStatOtherDetailVO> voMap = vos.stream().collect(
                    Collectors.toMap(
                            AccountDayStatOtherDetailVO::getAccountId,
                            AccountDayStatOtherDetailVO -> AccountDayStatOtherDetailVO)
            );

            //累计用户数
            List<Map<String, Object>> cumulativeNumberOfUsers = accountDayStatDao.selectCumulativeNumberOfUsers(parseTime(dto.getEndTime()),
                    dto.getBrandId(), accountIdList);
            Map<Integer, Integer> userCount = cumulativeNumberOfUsers.stream().collect(Collectors.toMap(
                    map -> Integer.parseInt(map.get("accountId").toString()),
                    map -> Integer.parseInt(map.get("cumulativeNumberOfUsers").toString())
            ));

            for (Map.Entry<Integer, RevenueVO> map : revenueMap.entrySet()) {
                Integer accountId = map.getKey();
                RevenueVO revenueVO = map.getValue();
                //计算净收入
                if (Objects.nonNull(revenueVO.getOperatingIncome()) && Objects.nonNull(revenueVO.getOperatingExpenses())){
                    revenueVO.setOperatingNetIncome(NumberUtil.sub(revenueVO.getOperatingIncome(), revenueVO.getOperatingExpenses()));
                }
                //设置区域名称
                revenueVO.setAccountName(accountMap.get(accountId));
                //设置其他收支
                AccountDayStatOtherDetailVO vo =  voMap.get(accountId);
                if (Objects.nonNull(vo)){
                    revenueVO.setOtherIncome(vo.getIncome().doubleValue());
                    revenueVO.setOtherExpenses(vo.getExpend().doubleValue());
                    revenueVO.setOtherIncomeCount(vo.getIncomeCount().intValue());
                    revenueVO.setOtherExpensesCount(vo.getExpendCount().intValue());
                }else {
                    revenueVO.setOtherIncome(0D);
                    revenueVO.setOtherExpenses(0D);
                    revenueVO.setOtherIncomeCount(0);
                    revenueVO.setOtherExpensesCount(0);
                }
                //设置累计用户数
                revenueVO.setCumulativeNumberOfUsers(userCount.getOrDefault(accountId, 0));
                //计算骑行订单金额和骑行订单退款金额
                revenueVO.setRideOrderIncome(NumberUtil.add(revenueVO.getCyclingIncome(), revenueVO.getUserFineIncome()));
                revenueVO.setRideOrderRefund(NumberUtil.add(revenueVO.getCyclingExpenses(), revenueVO.getUserFineExpenses()));
            }
            return Result.success(new ArrayList<>(revenueMap.values()));
        }else {
            // 获取预统计数据
            Map<String, RevenueGroupDayVO> revenueMap = accountDayStatDao.getRevenueGroupDay(parseTime(dto.getStartTime()),
                    parseTime(dto.getEndTime()), dto.getBrandId(), accountIdList);


            Map<String, AccountDayStatOtherDetailVO> otherDataMap = new HashMap<>();
            //获取其他收支数据
            for (AccountDayStatOtherDetailVO vo : badOrderDao.selectOtherFinancialByAccountIdAndDay(dto.getStartTime(), dto.getEndTime(),
                    accountIdList, dto.getBrandId())) {
                otherDataMap.put(vo.getAccountId() + "_" + vo.getDate(), vo);
            }
            //获取计费车辆数
            Map<String, Integer> jfMap = new HashMap<>();
            List<Map<String, Object>> jfList = accountDayStatDao.selectJfcls(accountIdList, dto.getStartTime(), dto.getEndTime());
            for (Map<String, Object> map : jfList) {
                int count = Integer.parseInt(map.getOrDefault("jfcls", 0).toString());
                Integer statDate = parseTime(DateUtil.parse(map.getOrDefault("statDate", 0).toString(), "yyyy-MM-dd"));
                jfMap.put(Integer.parseInt(map.getOrDefault("accountId", 0).toString()) + "_" + statDate, count);
            }

            //填充数据
            for (Map.Entry<String, RevenueGroupDayVO> map : revenueMap.entrySet()) {
                String key = map.getKey();
                RevenueGroupDayVO revenueGroupDayVO = map.getValue();
                //计算净收入
                if (Objects.nonNull(revenueGroupDayVO.getOperatingIncome()) && Objects.nonNull(revenueGroupDayVO.getOperatingExpenses())){
                    revenueGroupDayVO.setOperatingNetIncome(NumberUtil.sub(revenueGroupDayVO.getOperatingIncome(), revenueGroupDayVO.getOperatingExpenses()));
                }
                //设置区域名称
                revenueGroupDayVO.setAccountName(accountMap.get(revenueGroupDayVO.getAccountId()));
                revenueGroupDayVO.setDay(formatDate(key.split("_")[1]));
                AccountDayStatOtherDetailVO accountDayStatOtherDetailVO = otherDataMap.get(key);
                if (Objects.nonNull(accountDayStatOtherDetailVO)){
                    revenueGroupDayVO.setOtherIncome(accountDayStatOtherDetailVO.getIncome().doubleValue());
                    revenueGroupDayVO.setOtherExpenses(accountDayStatOtherDetailVO.getExpend().doubleValue());
                    revenueGroupDayVO.setOtherIncomeCount(accountDayStatOtherDetailVO.getIncomeCount().intValue());
                    revenueGroupDayVO.setOtherExpensesCount(accountDayStatOtherDetailVO.getExpendCount().intValue());
                }
                //计费数据
                revenueGroupDayVO.setJfcls(jfMap.getOrDefault(key, 0));
                //计算骑行订单金额和骑行订单退款金额
                revenueGroupDayVO.setCyclingOrderRevenueAmount(NumberUtil.add(revenueGroupDayVO.getCyclingIncome(), revenueGroupDayVO.getUserFineIncome()));
                revenueGroupDayVO.setRefundAmountForRidingOrders(NumberUtil.add(revenueGroupDayVO.getCyclingExpenses(), revenueGroupDayVO.getUserFineExpenses()));
            }


            List<RevenueGroupDayVO> revenueGroupDayVOS = revenueMap.values().stream()
                    .sorted(Comparator.comparingInt(RevenueGroupDayVO::getAccountId)
                            .thenComparing(RevenueGroupDayVO::getDay, Comparator.reverseOrder()))
                    .collect(Collectors.toCollection(ArrayList::new));

            return Result.success(revenueGroupDayVOS);
        }
    }


    /**
     * 获取yyyyMMdd格式的时间
     *
     * @param date
     * @return
     */
    private Integer parseTime(Date date) {
        if (date == null) {
            return null;
        }
        return Integer.parseInt(DateUtil.format(date, "yyyyMMdd"));
    }


    /**
     * 格式化日期字符串
     * @param dateStr 日期字符串
     * @return        String
     */
    private String formatDate(String dateStr) {
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(dateStr, inputFormatter);
        return date.format(outputFormatter);
    }
}
